﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Util.Props;

namespace Util
{
    public class SaxXmlReader
    {
        public delegate void startElement(String uri, String localName, String qName, Dictionary<String,String> attributes);
        public delegate void characters(char[] ch, int start, int length);
        public delegate void endElement(String uri, String localName, String qName);
        public delegate void setDocumentLocator(ILocator locator) ;

        private startElement startElementHandler;
        private characters charactersHandler;
        private endElement endElementHandler;
        private setDocumentLocator setDocumentLocatorHandler;

        public SaxXmlReader()
        { 
        }

        public void setContentHandler(ConfigHandler handler)
        {
            startElementHandler += handler.startElement;
            charactersHandler += handler.characters;
            endElementHandler += handler.endElement;
        }

        public void parse(String uri)
        {
            using (XmlReader reader = XmlReader.Create(uri))
            {
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            if (startElementHandler == null)
                                continue;
                            Boolean isEmptyElement = reader.IsEmptyElement;
                            String readerLocalName = reader.LocalName;
                            String readerName = reader.Name;
                            // if go forward the Name is overwrited.
                            Dictionary<String,String> attrs = new  Dictionary<String,String>(reader.AttributeCount);
                            while (reader.MoveToNextAttribute()) 
                            {
                                attrs.Add(reader.Name, reader.Value);
                            }
                            startElementHandler(uri, readerLocalName, readerName, attrs);
                            
                            if (isEmptyElement)
                            {
                                if (endElementHandler == null)
                                    continue;
                                endElementHandler(uri, readerLocalName, readerName);                            
                            }
                            break;
                        case XmlNodeType.Text:
                            if (charactersHandler != null)
                                charactersHandler(reader.Value.ToCharArray(), 0, reader.Value.Length);
                            break;
                        //case XmlNodeType.XmlDeclaration:
                        //case XmlNodeType.ProcessingInstruction:
                        //    writer.WriteProcessingInstruction(reader.Name, reader.Value);
                        //    break;
                        //case XmlNodeType.Comment:
                        //    writer.WriteComment(reader.Value);
                        //    break;
                        case XmlNodeType.EndElement:
                            if (endElementHandler != null)
                                endElementHandler(uri, reader.LocalName, reader.Name);
                            break;
                    }

                }
            }
        }
    }
}
